#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
统一验证器模块
合并智能验证和基础验证功能，提供统一的参数验证接口
"""

import json
import re
from typing import Dict, List, Any, Optional, Union
from datetime import datetime

class UnifiedValidator:
    """统一验证器 - 合并智能验证和基础验证功能"""
    
    def __init__(self):
        # 支持的类型定义
        self.supported_types = {
            'variable_types': ['continuous', 'integer', 'binary'],
            'optimization_types': ['minimize', 'maximize'],
            'constraint_types': ['equality', 'inequality', 'less_equal', 'greater_equal'],
            'uncertainty_types': ['normal', 'uniform', 'triangular', 'beta', 'gamma', 'exponential', 'scenario'],
            'algorithm_types': ['genetic_algorithm', 'particle_swarm', 'simulated_annealing', 'differential_evolution', 'adaptive_ga']
        }
        
        # 表达式验证模式
        self.expression_patterns = {
            'variable_name': r'^[a-zA-Z][a-zA-Z0-9_]*$',
            'mathematical_expression': r'^[a-zA-Z0-9+\-*/()\.\s]+$',
            'number': r'^-?\d+(\.\d+)?$'
        }
        
        # 常见错误映射（智能修正）
        self.error_mappings = {
            'discrete': 'scenario',
            'categorical': 'scenario',
            'min': 'minimize',
            'max': 'maximize',
            'eq': 'equality',
            'ineq': 'inequality',
            'ga': 'genetic_algorithm',
            'pso': 'particle_swarm',
            'sa': 'simulated_annealing',
            'de': 'differential_evolution'
        }
    
    def validate_variable(self, name: str, var_type: str, lower_bound: float = None, upper_bound: float = None) -> Dict[str, Any]:
        """验证决策变量"""
        result = {
            'valid': True,
            'warnings': [],
            'suggestions': [],
            'auto_fix': None
        }
        
        # 验证变量名
        if not re.match(self.expression_patterns['variable_name'], name):
            result['valid'] = False
            result['error'] = f"变量名 '{name}' 格式不正确，必须以字母开头，只能包含字母、数字和下划线"
            return result
        
        # 验证变量类型
        var_type = var_type.lower()
        if var_type not in self.supported_types['variable_types']:
            # 尝试智能修正
            corrected_type = self._auto_correct_type(var_type, self.supported_types['variable_types'])
            result['valid'] = False
            result['error'] = f"不支持的变量类型: {var_type}"
            result['auto_fix'] = {
                'type': corrected_type or 'continuous',
                'confidence': 0.8 if corrected_type else 0.6,
                'reason': f"根据输入 '{var_type}' 推荐使用 '{corrected_type or 'continuous'}'"
            }
            result['suggestions'] = [f"支持的类型: {', '.join(self.supported_types['variable_types'])}"] 
            return result
        
        # 验证边界
        if lower_bound is not None and upper_bound is not None:
            if lower_bound >= upper_bound:
                result['valid'] = False
                result['error'] = "下界必须小于上界"
                return result
        
        # 类型特定验证
        if var_type == 'binary':
            if lower_bound is not None and lower_bound != 0:
                result['warnings'].append("二进制变量的下界通常为0")
            if upper_bound is not None and upper_bound != 1:
                result['warnings'].append("二进制变量的上界通常为1")
        
        elif var_type == 'integer':
            if lower_bound is not None and not float(lower_bound).is_integer():
                result['warnings'].append("整数变量的下界应为整数")
            if upper_bound is not None and not float(upper_bound).is_integer():
                result['warnings'].append("整数变量的上界应为整数")
        
        return result
    
    def validate_objective(self, name: str, opt_type: str, expression: str = "", weight: float = 1.0) -> Dict[str, Any]:
        """验证目标函数"""
        result = {
            'valid': True,
            'warnings': [],
            'suggestions': [],
            'auto_fix': None
        }
        
        # 验证名称
        if not re.match(self.expression_patterns['variable_name'], name):
            result['valid'] = False
            result['error'] = f"目标函数名 '{name}' 格式不正确"
            return result
        
        # 验证优化类型
        opt_type = opt_type.lower()
        if opt_type not in self.supported_types['optimization_types']:
            corrected_type = self._auto_correct_type(opt_type, self.supported_types['optimization_types'])
            result['valid'] = False
            result['error'] = f"不支持的优化类型: {opt_type}"
            result['auto_fix'] = {
                'type': corrected_type or 'maximize',
                'confidence': 0.8 if corrected_type else 0.6
            }
            return result
        
        # 验证权重
        if weight <= 0:
            result['valid'] = False
            result['error'] = "目标函数权重必须大于0"
            return result
        
        # 验证表达式
        if expression:
            expr_result = self.validate_expression(expression)
            if not expr_result['valid']:
                result.update(expr_result)
                return result
            result['warnings'].extend(expr_result.get('warnings', []))
        
        return result
    
    def validate_constraint(self, name: str, constraint_type: str, expression: str = "") -> Dict[str, Any]:
        """验证约束条件"""
        result = {
            'valid': True,
            'warnings': [],
            'suggestions': []
        }
        
        # 验证名称
        if not re.match(self.expression_patterns['variable_name'], name):
            result['valid'] = False
            result['error'] = f"约束名 '{name}' 格式不正确"
            return result
        
        # 验证约束类型
        constraint_type = constraint_type.lower()
        if constraint_type not in self.supported_types['constraint_types']:
            corrected_type = self._auto_correct_type(constraint_type, self.supported_types['constraint_types'])
            result['valid'] = False
            result['error'] = f"不支持的约束类型: {constraint_type}"
            result['auto_fix'] = {
                'type': corrected_type or 'inequality',
                'confidence': 0.8 if corrected_type else 0.6
            }
            return result
        
        # 验证表达式
        if expression:
            expr_result = self.validate_expression(expression)
            if not expr_result['valid']:
                result.update(expr_result)
                return result
            result['warnings'].extend(expr_result.get('warnings', []))
        
        return result
    
    def validate_expression(self, expression: str, variables: List[str] = None) -> Dict[str, Any]:
        """验证数学表达式"""
        result = {
            'valid': True,
            'warnings': [],
            'suggestions': []
        }
        
        if not isinstance(expression, str):
            result['valid'] = False
            result['error'] = "表达式必须是字符串"
            return result
        
        expression = expression.strip()
        if not expression:
            result['valid'] = False
            result['error'] = "表达式不能为空"
            result['suggestions'] = [
                "请提供有效的数学表达式",
                "例如：2*x1 + 3*x2",
                "支持基本数学运算符：+, -, *, /, **, ()"
            ]
            return result
        
        # 基础语法检查
        if not re.match(self.expression_patterns['mathematical_expression'], expression):
            result['valid'] = False
            result['error'] = "表达式包含不支持的字符"
            return result
        
        # 检查括号匹配
        if expression.count('(') != expression.count(')'):
            result['valid'] = False
            result['error'] = "括号不匹配"
            return result
        
        # 检查变量引用
        if variables:
            expr_vars = re.findall(r'[a-zA-Z][a-zA-Z0-9_]*', expression)
            # 过滤掉数学函数名
            math_functions = ['sin', 'cos', 'tan', 'exp', 'log', 'sqrt', 'abs', 'pow', 'pi', 'e']
            expr_vars = [var for var in expr_vars if var not in math_functions]
            
            undefined_vars = [var for var in expr_vars if var not in variables]
            if undefined_vars:
                result['valid'] = False
                result['error'] = f"表达式中包含未定义的变量: {', '.join(undefined_vars)}"
                result['suggestions'] = [f"已定义的变量: {', '.join(variables)}"]
                return result
        
        # 检查常见问题
        if '/0' in expression.replace(' ', ''):
            result['warnings'].append("表达式可能包含除零操作")
        
        if expression.count('*') > expression.count('+') + expression.count('-') + 1:
            result['suggestions'].append("考虑使用括号明确运算优先级")
        
        return result
    
    def validate_uncertainty_parameter(self, name: str, uncertainty_type: str, data: Dict = None) -> Dict[str, Any]:
        """验证不确定性参数"""
        result = {
            'valid': True,
            'warnings': [],
            'suggestions': []
        }
        
        # 验证名称
        if not re.match(self.expression_patterns['variable_name'], name):
            result['valid'] = False
            result['error'] = f"参数名 '{name}' 格式不正确"
            return result
        
        # 验证不确定性类型
        uncertainty_type = uncertainty_type.lower()
        if uncertainty_type not in self.supported_types['uncertainty_types']:
            corrected_type = self._auto_correct_type(uncertainty_type, self.supported_types['uncertainty_types'])
            result['valid'] = False
            result['error'] = f"不支持的不确定性类型: {uncertainty_type}"
            result['auto_fix'] = {
                'type': corrected_type or 'normal',
                'confidence': 0.8 if corrected_type else 0.6
            }
            return result
        
        # 验证分布参数
        if data:
            param_result = self.validate_distribution_params(uncertainty_type, data)
            if not param_result['valid']:
                result.update(param_result)
                return result
            result['warnings'].extend(param_result.get('warnings', []))
        
        return result
    
    def validate_distribution_params(self, uncertainty_type: str, params: Dict) -> Dict[str, Any]:
        """验证分布参数"""
        result = {
            'valid': True,
            'warnings': [],
            'suggestions': []
        }
        
        if not isinstance(params, dict):
            result['valid'] = False
            result['error'] = "分布参数必须是字典格式"
            return result
        
        uncertainty_type = uncertainty_type.lower()
        
        # 检查必需参数
        required_params = self._get_required_params(uncertainty_type)
        missing_params = [p for p in required_params if p not in params]
        
        if missing_params:
            result['valid'] = False
            result['error'] = f"缺少必需参数: {', '.join(missing_params)}"
            result['suggestions'] = [f"必需参数: {', '.join(required_params)}"]
            return result
        
        # 验证参数值
        if uncertainty_type == 'normal':
            if params.get('std', 0) <= 0:
                result['valid'] = False
                result['error'] = "正态分布的标准差必须大于0"
                return result
        
        elif uncertainty_type == 'uniform':
            if params.get('min', 0) >= params.get('max', 1):
                result['valid'] = False
                result['error'] = "均匀分布的最小值必须小于最大值"
                return result
        
        elif uncertainty_type == 'triangular':
            min_val = params.get('min', 0)
            max_val = params.get('max', 1)
            mode_val = params.get('mode', 0.5)
            
            if not (min_val <= mode_val <= max_val):
                result['valid'] = False
                result['error'] = "三角分布的众数必须在最小值和最大值之间"
                return result
        
        return result
    
    def _auto_correct_type(self, input_type: str, valid_types: List[str]) -> Optional[str]:
        """自动修正类型"""
        input_lower = input_type.lower().strip()
        
        # 直接映射
        if input_lower in self.error_mappings:
            corrected = self.error_mappings[input_lower]
            if corrected in valid_types:
                return corrected
        
        # 模糊匹配
        for valid_type in valid_types:
            if input_lower in valid_type or valid_type in input_lower:
                return valid_type
        
        # 编辑距离匹配
        best_match = None
        min_distance = float('inf')
        
        for valid_type in valid_types:
            distance = self._edit_distance(input_lower, valid_type)
            if distance < min_distance and distance <= 2:  # 最多允许2个字符差异
                min_distance = distance
                best_match = valid_type
        
        return best_match
    
    def _edit_distance(self, s1: str, s2: str) -> int:
        """计算编辑距离"""
        if len(s1) < len(s2):
            return self._edit_distance(s2, s1)
        
        if len(s2) == 0:
            return len(s1)
        
        previous_row = list(range(len(s2) + 1))
        for i, c1 in enumerate(s1):
            current_row = [i + 1]
            for j, c2 in enumerate(s2):
                insertions = previous_row[j + 1] + 1
                deletions = current_row[j] + 1
                substitutions = previous_row[j] + (c1 != c2)
                current_row.append(min(insertions, deletions, substitutions))
            previous_row = current_row
        
        return previous_row[-1]
    
    def _get_required_params(self, uncertainty_type: str) -> List[str]:
        """获取分布类型的必需参数"""
        param_map = {
            'normal': ['mean', 'std'],
            'uniform': ['min', 'max'],
            'triangular': ['min', 'max', 'mode'],
            'beta': ['alpha', 'beta'],
            'gamma': ['shape', 'scale'],
            'exponential': ['rate'],
            'scenario': ['scenarios', 'probabilities']
        }
        return param_map.get(uncertainty_type, [])